import os
import json
import logging
import time
import os
from typing import Optional, Dict, Any, Union

# 导入数据库工具
from utils.db_utils import get_db_connection, execute_sql, execute_sql_update

# 配置日志
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger = logging.getLogger('video_dispose_model')
logger.setLevel(logging.INFO)
logger.addHandler(handler)

class VideoDisposeModel:
    """
    基于freefishchn数据库中video_dispose表的视频处理任务模型
    
    此类用于表示和管理视频处理任务，包括任务ID、状态、请求数据和响应数据等信息。
    支持序列化和反序列化操作，便于存储和传输。
    """
    
    # 定义任务状态枚举
    class Status:
        PENDING = "pending"      # 等待处理
        PROCESSING = "processing" # 处理中
        COMPLETED = "completed"   # 处理完成
        FAILED = "failed"         # 处理失败
        CANCELLED = "cancelled"   # 已取消
    
    def __init__(self, id: int = None, task_id: str = None, status: str = Status.PENDING,
                 request_data: Union[str, Dict[str, Any]] = None, 
                 response_data: Union[str, Dict[str, Any]] = None, 
                 created_at: int = None, updated_at: int = None):
        """
        初始化视频处理任务模型
        
        Args:
            id: 数据库ID，自增主键
            task_id: 任务ID，如果为None则自动生成
            status: 任务状态，默认为pending
            request_data: 请求数据，可以是JSON字符串或字典
            response_data: 响应数据，可以是JSON字符串或字典
            created_at: 创建时间戳
            updated_at: 更新时间戳
        """
        # 数据库ID
        self.id = id
        # 生成唯一任务ID（如果未提供）
        self.task_id = task_id or self._generate_task_id()
        # 设置任务状态
        self.status = status
        # 设置创建时间（时间戳格式）
        self.created_at = created_at or int(time.time())
        # 设置更新时间（时间戳格式）
        self.updated_at = updated_at or int(time.time())
        
        # 存储请求数据（自动转换为JSON字符串）
        self.request = request_data if isinstance(request_data, str) else \
                      json.dumps(request_data) if request_data else "{}"
        
        # 存储响应数据（自动转换为JSON字符串）
        self.response = response_data if isinstance(response_data, str) else \
                       json.dumps(response_data) if response_data else "{}"
    
    def _generate_task_id(self) -> str:
        """生成唯一的任务ID"""
        return f"task_{int(time.time())}_{os.urandom(4).hex()}"
    
    def update_status(self, new_status: str) -> None:
        """
        更新任务状态
        
        Args:
            new_status: 新的任务状态
        """
        if new_status not in [self.Status.PENDING, self.Status.PROCESSING,
                             self.Status.COMPLETED, self.Status.FAILED,
                             self.Status.CANCELLED]:
            raise ValueError(f"无效的任务状态: {new_status}")
        
        self.status = new_status
        self.updated_at = int(time.time())
        
        logger.info(f"任务 {self.task_id} 状态更新为: {new_status}")
    
    def set_request_data(self, request_data: Union[str, Dict[str, Any]]) -> None:
        """
        设置请求数据
        
        Args:
            request_data: 请求数据，可以是JSON字符串或字典
        """
        self.request = request_data if isinstance(request_data, str) else json.dumps(request_data)
        self.updated_at = int(time.time())
    
    def set_response_data(self, response_data: Union[str, Dict[str, Any]]) -> None:
        """
        设置响应数据
        
        Args:
            response_data: 响应数据，可以是JSON字符串或字典
        """
        self.response = response_data if isinstance(response_data, str) else json.dumps(response_data)
        self.updated_at = int(time.time())
    
    def get_request_data(self) -> Dict[str, Any]:
        """
        获取请求数据（解析为字典）
        
        Returns:
            解析后的请求数据字典
        """
        try:
            return json.loads(self.request)
        except json.JSONDecodeError:
            logger.error(f"任务 {self.task_id} 请求数据解析失败")
            return {}
    
    def get_response_data(self) -> Dict[str, Any]:
        """
        获取响应数据（解析为字典）
        
        Returns:
            解析后的响应数据字典
        """
        try:
            return json.loads(self.response)
        except json.JSONDecodeError:
            logger.error(f"任务 {self.task_id} 响应数据解析失败")
            return {}
    
    def to_dict(self) -> Dict[str, Any]:
        """
        将模型转换为字典格式
        
        Returns:
            模型的字典表示
        """
        return {
            'id': self.id,
            'task_id': self.task_id,
            'status': self.status,
            'request': self.request,
            'response': self.response,
            'created_at': self.created_at,
            'updated_at': self.updated_at
        }
    
    def to_json(self) -> str:
        """
        将模型转换为JSON字符串
        
        Returns:
            模型的JSON字符串表示
        """
        return json.dumps(self.to_dict(), ensure_ascii=False)
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'VideoDisposeModel':
        """
        从字典创建模型实例
        
        Args:
            data: 包含模型数据的字典
        
        Returns:
            创建的模型实例
        """
        model = cls(
            id=data.get('id'),
            task_id=data.get('task_id'),
            status=data.get('status', cls.Status.PENDING),
            request_data=data.get('request'),
            response_data=data.get('response'),
            created_at=data.get('created_at'),
            updated_at=data.get('updated_at')
        )
        
        return model
    
    @classmethod
    def from_json(cls, json_str: str) -> 'VideoDisposeModel':
        """
        从JSON字符串创建模型实例
        
        Args:
            json_str: 包含模型数据的JSON字符串
        
        Returns:
            创建的模型实例
        """
        data = json.loads(json_str)
        return cls.from_dict(data)
    
    def __str__(self) -> str:
        """返回模型的字符串表示"""
        return f"VideoDisposeModel(task_id={self.task_id}, status={self.status}, created_at={self.created_at})"
    
    def __repr__(self) -> str:
        """返回模型的详细字符串表示"""
        return self.__str__()

# 创建模型管理器类，用于管理多个任务模型
class VideoDisposeModelManager:
    """
    视频处理任务模型管理器
    
    负责管理多个VideoDisposeModel实例，提供任务的创建、查询、更新和删除等操作。
    支持内存存储和数据库持久化。
    """
    
    def __init__(self):
        """初始化模型管理器"""
        self.tasks = {}
        self._init_database_table()
    
    def _init_database_table(self):
        """初始化数据库表结构（如果不存在）"""
        try:
            # 确保表存在（仅用于安全检查，不应在生产环境中使用）
            query = """SHOW TABLES LIKE 'video_dispose'"""
            result = execute_sql(query)
            if not result:
                logger.warning("video_dispose表不存在，无法进行数据库操作")
        except Exception as e:
            logger.error(f"检查数据库表失败: {str(e)}")
    
    def create_task(self, request_data: Union[str, Dict[str, Any]], task_id: str = None) -> VideoDisposeModel:
        """
        创建新的视频处理任务
        
        Args:
            request_data: 请求数据
            task_id: 自定义任务ID，如果为None则自动生成
        
        Returns:
            创建的任务模型实例
        """
        task = VideoDisposeModel(request_data=request_data, task_id=task_id)
        
        # 存储到数据库
        try:
            query = """
                INSERT INTO video_dispose (task_id, request, response, status, created_at, updated_at)
                VALUES (%s, %s, %s, %s, %s, %s)
            """
            params = (
                task.task_id, 
                task.request, 
                task.response, 
                task.status, 
                task.created_at, 
                task.updated_at
            )
            affected_rows = execute_sql_update(query, params)
            
            if affected_rows > 0:
                # 获取自增ID
                query = "SELECT LAST_INSERT_ID() as id"
                result = execute_sql(query)
                if result and 'id' in result[0]:
                    task.id = result[0]['id']
                logger.info(f"任务 {task.task_id} 已创建并保存到数据库")
        except Exception as e:
            logger.error(f"保存任务到数据库失败: {str(e)}")
        
        return task
    
    def get_task(self, task_id: str) -> Optional[VideoDisposeModel]:
        """
        根据任务ID获取任务模型
        
        Args:
            task_id: 任务ID
        
        Returns:
            任务模型实例，如果不存在则返回None
        """
        # 先从内存中查找
        if task_id in self.tasks:
            return self.tasks[task_id]
        
        # 从数据库中查找
        try:
            query = """
                SELECT * FROM video_dispose WHERE task_id = %s
            """
            result = execute_sql(query, (task_id,))
            
            if result:
                task_data = result[0]
                task = VideoDisposeModel(
                    id=task_data.get('id'),
                    task_id=task_data.get('task_id'),
                    status=task_data.get('status'),
                    request_data=task_data.get('request'),
                    response_data=task_data.get('response'),
                    created_at=task_data.get('created_at'),
                    updated_at=task_data.get('updated_at')
                )
                
                # 缓存到内存
                self.tasks[task.task_id] = task
                return task
        except Exception as e:
            logger.error(f"从数据库获取任务失败: {str(e)}")
        
        return None
    
    def update_task(self, task: VideoDisposeModel) -> None:
        """
        更新任务模型
        
        Args:
            task: 任务模型实例
        """
        # 更新到数据库
        try:
            # 确保响应数据是JSON字符串格式
            response_data = task.response if isinstance(task.response, str) else json.dumps(task.response)
            
            if task.id:
                query = """
                    UPDATE video_dispose 
                    SET status = %s, request = %s, response = %s, updated_at = %s 
                    WHERE id = %s
                """
                params = (task.status, task.request, response_data, task.updated_at, task.id)
            else:
                query = """
                    UPDATE video_dispose 
                    SET status = %s, request = %s, response = %s, updated_at = %s 
                    WHERE task_id = %s
                """
                params = (task.status, task.request, response_data, task.updated_at, task.task_id)
            
            affected_rows = execute_sql_update(query, params)
            if affected_rows > 0:
                # 更新内存中的数据
                self.tasks[task.task_id] = task
                logger.info(f"任务 {task.task_id} 已更新到数据库并缓存")
            else:
                logger.warning(f"任务 {task.task_id} 数据库更新未影响任何行")
        except Exception as e:
            logger.error(f"更新任务到数据库失败: {str(e)}")
    
    def delete_task(self, task_id: str) -> bool:
        """
        删除任务模型
        
        Args:
            task_id: 任务ID
        
        Returns:
            如果删除成功返回True，否则返回False
        """
        # 从数据库中删除
        try:
            query = "DELETE FROM video_dispose WHERE task_id = %s"
            affected_rows = execute_sql_update(query, (task_id,))
            if affected_rows > 0:
                # 从内存中删除
                if task_id in self.tasks:
                    del self.tasks[task_id]
                logger.info(f"任务 {task_id} 已从数据库和内存中删除")
                return True
            else:
                logger.warning(f"数据库中未找到要删除的任务: {task_id}")
        except Exception as e:
            logger.error(f"从数据库删除任务失败: {str(e)}")
        
        # 检查内存中是否存在任务
        if task_id in self.tasks:
            del self.tasks[task_id]
            logger.info(f"任务 {task_id} 已从内存中删除（数据库中不存在）")
            return True
            
        logger.warning(f"尝试删除不存在的任务: {task_id}")
        return False
    
    def list_tasks(self, status: str = None) -> list[VideoDisposeModel]:
        """
        列出所有任务或指定状态的任务
        
        Args:
            status: 任务状态过滤，如果为None则列出所有任务
        
        Returns:
            任务模型实例列表
        """
        # 优先从数据库获取最新数据
        try:
            if status:
                query = "SELECT * FROM video_dispose WHERE status = %s ORDER BY created_at DESC"
                params = (status,)
            else:
                query = "SELECT * FROM video_dispose ORDER BY created_at DESC"
                params = ()
            
            results = execute_sql(query, params)
            
            if results:
                tasks = []
                for task_data in results:
                    task = VideoDisposeModel(
                        id=task_data.get('id'),
                        task_id=task_data.get('task_id'),
                        status=task_data.get('status'),
                        request_data=task_data.get('request'),
                        response_data=task_data.get('response'),
                        created_at=task_data.get('created_at'),
                        updated_at=task_data.get('updated_at')
                    )
                    tasks.append(task)
                    # 更新内存缓存
                    self.tasks[task.task_id] = task
                return tasks
        except Exception as e:
            logger.error(f"从数据库获取任务列表失败: {str(e)}")
        
        # 如果数据库查询失败，返回内存中的数据
        if status:
            return [task for task in self.tasks.values() if task.status == status]
        return list(self.tasks.values())

# 创建全局模型管理器实例
record_manager = VideoDisposeModelManager()